home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / gif_c.zip / GIFENCOD.C < prev    next >
C/C++ Source or Header  |  1989-03-22  |  4KB  |  280 lines

  1.  
  2. /*****************************************************************************
  3.  *
  4.  * GIFENCODE.C    - GIF Image compression interface
  5.  *
  6.  * GIFEncode( FName, GHeight, GWidth, GInterlace, Background, 
  7.  *          BitsPerPixel, Red, Green, Blue, GetPixel )
  8.  *
  9.  *****************************************************************************/
  10.  
  11. #include <stdio.h>
  12.  
  13. /*
  14.  * Pointer to function returning an int
  15.  */
  16. typedef int (* ifunptr)();
  17.  
  18. #define TRUE 1
  19. #define FALSE 0
  20.  
  21. static int Width, Height;
  22. static int curx, cury;
  23. static long CountDown;
  24. static int Pass = 0;
  25. static int Interlace;
  26.  
  27. /*
  28.  * Bump the 'curx' and 'cury' to point to the next pixel
  29.  */
  30. static
  31. BumpPixel()
  32. {
  33.     /*
  34.      * Bump the current X position
  35.      */
  36.     curx++;
  37.  
  38.     /*
  39.      * If we are at the end of a scan line, set curx back to the beginning
  40.      * If we are interlaced, bump the cury to the appropriate spot,
  41.      * otherwise, just increment it.
  42.      */
  43.     if( curx == Width ) {
  44.         curx = 0;
  45.  
  46.             if( !Interlace ) 
  47.             cury++;
  48.         else {
  49.              switch( Pass ) {
  50.          
  51.                    case 0:
  52.                       cury += 8;
  53.                       if( cury >= Height ) {
  54.                   Pass++;
  55.                 cury = 4;
  56.                 }
  57.                           break;
  58.           
  59.                    case 1:
  60.                       cury += 8;
  61.                       if( cury >= Height ) {
  62.                   Pass++;
  63.                 cury = 2;
  64.                 }
  65.               break;
  66.           
  67.                    case 2:
  68.                       cury += 4;
  69.                       if( cury >= Height ) {
  70.                          Pass++;
  71.                          cury = 1;
  72.                       }
  73.                       break;
  74.               
  75.                    case 3:
  76.                       cury += 2;
  77.                       break;
  78.             }
  79.         }
  80.     }
  81. }
  82.  
  83. /*
  84.  * Return the next pixel from the image
  85.  */
  86. GIFNextPixel( getpixel )
  87. ifunptr getpixel;
  88. {
  89.     int r;
  90.  
  91.     if( CountDown == 0 )
  92.         return EOF;
  93.  
  94.     CountDown--;
  95.  
  96.     r = ( * getpixel )( curx, cury );
  97.  
  98.     BumpPixel();
  99.  
  100.     return r;
  101. }
  102.  
  103. /* public */
  104.  
  105. GIFEncode( FName, GWidth, GHeight, GInterlace, Background, 
  106.        BitsPerPixel, Red, Green, Blue, GetPixel )
  107.      
  108. char *FName;
  109. int GWidth, GHeight;
  110. int GInterlace;
  111. int Background;
  112. int BitsPerPixel;
  113. int Red[], Green[], Blue[];
  114. ifunptr GetPixel;
  115.  
  116. {
  117.     FILE *fp;
  118.     int B;
  119.     int RWidth, RHeight;
  120.     int LeftOfs, TopOfs;
  121.     int Resolution;
  122.     int ColorMapSize;
  123.     int InitCodeSize;
  124.     int i;
  125.  
  126.     Interlace = GInterlace;
  127.     
  128.     ColorMapSize = 1 << BitsPerPixel;
  129.     
  130.     RWidth = Width = GWidth;
  131.     RHeight = Height = GHeight;
  132.     LeftOfs = TopOfs = 0;
  133.     
  134.     Resolution = BitsPerPixel;
  135.  
  136.     /*
  137.      * Calculate number of bits we are expecting
  138.      */
  139.     CountDown = (long)Width * (long)Height;
  140.  
  141.     /*
  142.      * Indicate which pass we are on (if interlace)
  143.      */
  144.     Pass = 0;
  145.  
  146.     /*
  147.      * The initial code size
  148.      */
  149.     if( BitsPerPixel <= 1 )
  150.         InitCodeSize = 2;
  151.     else
  152.         InitCodeSize = BitsPerPixel;
  153.  
  154.     /*
  155.      * Set up the current x and y position
  156.      */
  157.     curx = cury = 0;
  158.  
  159.     /*
  160.      * Open the GIF file for binary write
  161.      */
  162.     fp = fopen( FName, "wb" );
  163.  
  164.     if( fp == (FILE *)0 ) {
  165.         printf( "error: could not open output file\n" );
  166.         exit(1);
  167.     }
  168.  
  169.     /*
  170.      * Write the Magic header
  171.      */
  172.     fwrite( "GIF87a", 1, 6, fp );
  173.  
  174.     /*
  175.      * Write out the screen width and height
  176.      */
  177.     Putword( RWidth, fp );
  178.     Putword( RHeight, fp );
  179.  
  180.     /*
  181.      * Indicate that there is a global colour map
  182.      */
  183.     B = 0x80;    /* Yes, there is a color map */
  184.  
  185.     /*
  186.      * OR in the resolution
  187.      */
  188.     B |= (Resolution - 1) << 5;
  189.  
  190.     /*
  191.      * OR in the Bits per Pixel
  192.      */
  193.     B |= (BitsPerPixel - 1);
  194.  
  195.     /*
  196.      * Write it out
  197.      */
  198.     fputc( B, fp );
  199.  
  200.     /*
  201.      * Write out the Background colour
  202.      */
  203.     fputc( Background, fp );
  204.  
  205.     /*
  206.      * Byte of 0's (future expansion)
  207.      */
  208.     fputc( 0, fp );
  209.  
  210.     /*
  211.      * Write out the Global Colour Map
  212.      */
  213.          for( i=0; i<ColorMapSize; i++ ) {
  214.         fputc( Red[i], fp );
  215.         fputc( Green[i], fp );
  216.         fputc( Blue[i], fp );
  217.     }
  218.  
  219.     /*
  220.      * Write an Image separator
  221.      */
  222.     fputc( ',', fp );
  223.  
  224.     /*
  225.      * Write the Image header
  226.      */
  227.  
  228.     Putword( LeftOfs, fp );
  229.     Putword( TopOfs, fp );
  230.     Putword( Width, fp );
  231.     Putword( Height, fp );
  232.  
  233.     /*
  234.      * Write out whether or not the image is interlaced
  235.      */
  236.     if( Interlace )
  237.         fputc( 0x40, fp );
  238.     else
  239.         fputc( 0x00, fp );
  240.  
  241.     /*
  242.      * Write out the initial code size
  243.      */
  244.     fputc( InitCodeSize, fp );
  245.  
  246.     /*
  247.      * Go and actually compress the data
  248.      */
  249.     compress( InitCodeSize+1, fp, GetPixel );
  250.  
  251.     /*
  252.      * Write out a Zero-length packet (to end the series)
  253.      */
  254.     fputc( 0, fp );
  255.  
  256.     /*
  257.      * Write the GIF file terminator
  258.      */
  259.     fputc( ';', fp );
  260.  
  261.     /*
  262.      * And close the file
  263.      */
  264.     fclose( fp );
  265.     
  266. }
  267.  
  268. /*
  269.  * Write out a word to the GIF file
  270.  */
  271. static
  272. Putword( w, fp )
  273. int w;
  274. FILE *fp;
  275. {
  276.     fputc( w & 0xff, fp );
  277.     fputc( (w / 256) & 0xff, fp );
  278. }
  279.  
  280.